#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "esp_timer.h"
#include "esp_app_desc.h"
#include "esp_heap_caps.h"
#include "esp_mac.h"
#include "esp_flash.h"
#include "api_map.h"

bool user_call_reboot = false;
static void reboot_timer_cb(void *arg)
{
    user_call_reboot = true;
    esp_restart();
}

static void reboot(http_server_t server, httpd_ws_frame_t *frame, void *data)
{
    ws_reply_status(server, frame, "reboot", 0);
    const esp_timer_create_args_t reboot_timer_args = {
        .callback = &reboot_timer_cb,
        .name = "reboot"};
    esp_timer_handle_t reboot_timer = NULL;
    ESP_ERROR_CHECK(esp_timer_create(&reboot_timer_args, &reboot_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(reboot_timer, 1000 * 1000));
}

static void get_chip_info(http_server_t server, httpd_ws_frame_t *frame, void *data)
{
    uint32_t size = 0;
    uint8_t macs[6] = {0};
    const esp_app_desc_t *app_desc = esp_app_get_description();
    esp_flash_get_size(NULL, &size);
    esp_base_mac_addr_get(macs);

    uint16_t len = 0;
    char *str = (char *)server->data;
    len += sprintf(&str[len], "{");
    len += sprintf(&str[len], "\"api\":\"get_chip_info\",");
    len += sprintf(&str[len], "\"data\":{");
    len += sprintf(&str[len], "\"chip\":\"" chip_name "\",");
    len += sprintf(&str[len], "\"flash\":%ld,", size);
    size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
    len += sprintf(&str[len], "\"ram\":%ld,", size);
#ifdef CONFIG_SPIRAM
    size = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
    len += sprintf(&str[len], "\"psram\":%ld,", size);
#endif
    len += sprintf(&str[len], "\"mac\":\"" MACSTR "\",", MAC2STR(macs));
    len += sprintf(&str[len], "\"version\":\"%s\",", app_desc->version);
    len += sprintf(&str[len], "\"time\":\"%s\",", app_desc->time);
    len += sprintf(&str[len], "\"api_version\":\"" API_VERSION "\",");
    len += sprintf(&str[len], "\"io\":%d", CONFIG_SOC_GPIO_PIN_COUNT);
    len += sprintf(&str[len], "}");
    len += sprintf(&str[len], "}");
    frame->payload = server->data;
    frame->len = len;
}

static void chip_info_init(void)
{
    ADD_API_ITEM(get_chip_info);
    ADD_API_ITEM(reboot);
}
ADD_API(chip_info_init)
